package com.cms.utils;

import com.cms.common.BeanFactory;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.*;
import freemarker.template.utility.DeepUnwrap;
import org.apache.commons.beanutils.ConvertUtilsBean;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class FreeMarkerUtils {

    /**
     * ConvertUtilsBean
     */
    private static final ConvertUtilsBean CONVERT_UTILS = new ConvertUtilsBean();

    /**
     * BeansWrapper
     */
    private static final BeansWrapper DEFAULT_BEANS_WRAPPER = new BeansWrapperBuilder(Configuration.VERSION_2_3_25).build();

    /**
     * 获取参数
     *
     * @param name
     *            名称
     * @param type
     *            类型
     * @param params
     *            参数
     * @return 参数，若不存在则返回null
     */
    @SuppressWarnings("unchecked")
    public static <T> T getParameter(String name, Class<T> type, Map<String, TemplateModel> params) throws TemplateModelException {
        TemplateModel templateModel = params.get(name);
        if (templateModel != null) {
            Object value = DeepUnwrap.unwrap(templateModel);
            if (value != null) {
                return (T) CONVERT_UTILS.convert(value, type);
            }
        }
        return null;
    }

    /**
     * 获取参数
     *
     * @param index
     *            索引
     * @param type
     *            类型
     * @param arguments
     *            参数
     * @return 参数，若不存在则返回null
     */
    @SuppressWarnings("unchecked")
    public static <T> T getArgument(int index, Class<T> type, List<?> arguments) throws TemplateModelException {

        if (index >= 0 && index < arguments.size()) {
            Object argument = arguments.get(index);
            Object value;
            if (argument != null) {
                if (argument instanceof TemplateModel) {
                    value = DeepUnwrap.unwrap((TemplateModel) argument);
                } else {
                    value = argument;
                }
                if (value != null) {
                    return (T) CONVERT_UTILS.convert(value, type);
                }
            }
        }
        return null;
    }

    /**
     * 获取变量
     *
     * @param name
     *            名称
     * @param env
     *            环境变量
     * @return 变量
     */
    public static TemplateModel getVariable(String name, Environment env) throws TemplateModelException {

        return env.getVariable(name);
    }

    /**
     * 设置变量
     *
     * @param name
     *            名称
     * @param value
     *            变量值
     * @param env
     *            环境变量
     */
    public static void setVariable(String name, Object value, Environment env) throws TemplateException {

        if (value instanceof TemplateModel) {
            env.setVariable(name, (TemplateModel) value);
        } else {
            env.setVariable(name, DEFAULT_BEANS_WRAPPER.wrap(value));
        }
    }

    /**
     * 设置变量
     *
     * @param variables
     *            变量
     * @param env
     *            环境变量
     */
    public static void setVariables(Map<String, Object> variables, Environment env) throws TemplateException {

        for (Map.Entry<String, Object> entry : variables.entrySet()) {
            String name = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof TemplateModel) {
                env.setVariable(name, (TemplateModel) value);
            } else {
                env.setVariable(name, DEFAULT_BEANS_WRAPPER.wrap(value));
            }
        }
    }

    /**
     * 获取模板
     *
     * @param templatePath
     *                  模板路径
     * @return 模板
     */
    public static Template getTemplate(String templatePath){
        Configuration cfg = BeanFactory.getBean(Configuration.class);
        try {
            return cfg.getTemplate(templatePath);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
